﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesGDB;

namespace BesAsm.Emgaats.Core
{
  /// <summary>
  /// Provides input and output services for Models
  /// </summary>
  public class ModelIO
  {
    private XmlSerializer _serializer = null;

    public ModelIO()
    {
      _serializer = new XmlSerializer(typeof(Model));
    }

    /// <summary>
    /// Opens a model from the file system
    /// </summary>
    /// <param name="modelPath">The the path of the model root folder</param>
    /// <returns>A Model</returns>
    public Model Open(string modelPath)
    {
      string fileName = Model.GetConfigFileName(modelPath);
      try
      {
        using (StreamReader stream = new StreamReader(fileName))
        {
          using (XmlReader reader = XmlReader.Create(stream))
          {
            Model model = (Model)_serializer.Deserialize(reader);
            model.SetPath(modelPath);
            model.SetModelLayers();
            return model;
          }
        }
      }
      catch (Exception ex)
      {
        throw ex;
      }
    }

    /// <summary>
    /// Saves a model to the file system
    /// </summary>
    /// <param name="model">The Model to be saved</param>
    public void Save(Model model)
    {
      string fileName = model.GetPathIfSet(ModelPathComponent.ConfigFile);
      using (TextWriter writer = new StreamWriter(fileName))
      {
        _serializer.Serialize(writer, model);
      }
    }

    /// <summary>
    /// Saves a model to the file system to another location
    /// </summary>
    /// <param name="model">The Model to be saved</param>
    /// <param name="modelPath">The path where the model should be saved</param>
    /// <returns></returns>
    public void Save(Model model, string modelPath)
    {
      string fileName = model.GetPathIfSet(ModelPathComponent.ConfigFile);
      System.IO.FileInfo newConfigFileInfo = new System.IO.FileInfo(fileName);
      newConfigFileInfo.Directory.Create();
      Save(model);
      // Copy the PGDB
    }

    /// <summary>
    /// Creates a new model on the file system
    /// </summary>
    /// <param name="modelPath">The path at which to create a new model</param>
    /// <returns>A Model</returns>
    public Model New(string modelPath)
    {
      Model newModel = new Model();
      newModel.InitializeModel(modelPath);
      CreatePgdb(newModel, modelPath);
      // TODO: Have model determine its state instead
      newModel.State = ModelState.TemplateApplied;
      Save(newModel, modelPath);
      return newModel;
    }

    public void DeletePgdb(string fileName)
    {
      string pgdbPath = fileName;
      if (System.IO.File.Exists(pgdbPath))
        System.IO.File.Delete(pgdbPath);
    }

    public void CreatePgdb(Model model, string modelPath)
    {
      string pgdbFileName = model.GetPathIfSet(ModelPathComponent.Pgdb);
      DeletePgdb(pgdbFileName);
      IWorkspaceFactory wsf = new AccessWorkspaceFactory();
      string pgdbPath = model.GetPathIfSet(ModelPathComponent.RootFolder);
      wsf.Create(pgdbPath, System.IO.Path.GetFileName(pgdbFileName), null, 0);
    }


  }
}
